<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <style>
        html,
        body,
        #viewDiv {
            padding: 0;
            margin: 0;
            height: 100%;
            width: 100%;
        }

        #screenshotDiv {
            position: absolute;
            top: 0;
            left: 0;
            right: 0;
            bottom: 0;
            text-align: center;
            background-color: rgba(255, 255, 255, 0.8);
        }

        .hide {
            display: none;
        }

        img {
            border: 10px solid white;
            box-shadow: 2px 2px 5px 0 rgba(0, 0, 0, 0.5);
        }

        #screenshotDiv > * {
            margin: 0.5em;
        }

        .screenshotCursor {
            cursor: crosshair;
        }

        .action-button {
            padding: 0.6em;
            border: 1px solid #0079c1;
            text-align: center;
            background-color: white;
            cursor: pointer;
        }

        .action-button:hover,
        .action-button:focus {
            background: #0079c1;
            color: white;
        }

        #maskDiv {
            position: absolute;
            background: rgba(255, 51, 0, 0.1);
            border: 2px dashed rgb(255, 51, 0);
        }
    </style>
    <link href="https://js.arcgis.com/4.21/esri/themes/light/main.css" rel="stylesheet"/>
    <script src="https://js.arcgis.com/4.21/"></script>
    <script>
        require(["esri/WebScene", "esri/views/SceneView"], function (
            WebScene,
            SceneView
        ) {
            const webscene = new WebScene({
                portalItem: {
                    id: "19dcff93eeb64f208d09d328656dd492"
                }
            });

            const view = new SceneView({
                map: webscene,
                container: "viewDiv"
            });
            //清空左上角
            view.ui.empty("top-left");
            //添加截图按钮
            view.ui.add("screenshotBtn","top-left");
            //获取截图按钮
            const screenshotBtn = document.getElementById("screenshotBtn");

            const maskDiv = document.getElementById("maskDiv");

            //给截图按钮添加监听事件
            screenshotBtn.addEventListener("click", function () {
                screenshotBtn.classList.add("active");

                //下面两种写法一样
                //const viewDiv = document.getElementById("viewDiv").classList.add("screenshotCursor");
                view.container.classList.add("screenshotCursor");

                let area = null;

                const dragHandler = view.on("drag", function (event) {
                    // prevent navigation in the view
                    event.stopPropagation();

                    // when the user starts dragging or is dragging
                    if (event.action !== "end") {
                        // calculate the extent of the area selected by dragging the cursor
                        const xmin = clamp(
                            Math.min(event.origin.x, event.x),
                            0,
                            view.width
                        );
                        const xmax = clamp(
                            Math.max(event.origin.x, event.x),
                            0,
                            view.width
                        );
                        const ymin = clamp(
                            Math.min(event.origin.y, event.y),
                            0,
                            view.height
                        );
                        const ymax = clamp(
                            Math.max(event.origin.y, event.y),
                            0,
                            view.height
                        );
                        area = {
                            x: xmin,
                            y: ymin,
                            width: xmax - xmin,
                            height: ymax - ymin
                        };
                        // set the position of the div element that marks the selected area
                        setMaskPosition(area);
                    }
                    // when the user stops dragging
                    else {
                        // remove the drag event listener from the SceneView
                        dragHandler.remove();
                        // the screenshot of the selected area is taken
                        view
                            .takeScreenshot({ area: area, format: "png" })
                            .then(function (screenshot) {
                                // display a preview of the image
                                showPreview(screenshot);

                                // create the image for download
                                document.getElementById("downloadBtn").onclick = function () {
                                    const text = document.getElementById("textInput").value;
                                    // if a text exists, then add it to the image
                                    if (text) {
                                        const dataUrl = getImageWithText(screenshot, text);
                                        downloadImage(
                                            webscene.portalItem.title + ".png",
                                            dataUrl
                                        );
                                    }
                                    // otherwise download only the webscene screenshot
                                    else {
                                        downloadImage(
                                            webscene.portalItem.title + ".png",
                                            screenshot.dataUrl
                                        );
                                    }
                                };

                                // the screenshot mode is disabled
                                screenshotBtn.classList.remove("active");
                                view.container.classList.remove("screenshotCursor");
                                setMaskPosition(null);
                            });
                    }
                });

                function setMaskPosition(area) {
                    if (area) {
                        maskDiv.classList.remove("hide");
                        maskDiv.style.left = area.x + "px";
                        maskDiv.style.top = area.y + "px";
                        maskDiv.style.width = area.width + "px";
                        maskDiv.style.height = area.height + "px";
                    } else {
                        maskDiv.classList.add("hide");
                    }
                }

                function clamp(value, from, to) {
                    return value < from ? from : value > to ? to : value;
                }
            });

            function showPreview(screenshot) {
                screenshotDiv.classList.remove("hide");
                // add the screenshot dataUrl as the src of an image element
                const screenshotImage = document.getElementsByClassName(
                    "js-screenshot-image"
                )[0];
                screenshotImage.width = screenshot.data.width;
                screenshotImage.height = screenshot.data.height;
                screenshotImage.src = screenshot.dataUrl;
            }

            // returns a new image created by adding a custom text to the webscene image
            function getImageWithText(screenshot, text) {
                const imageData = screenshot.data;

                // to add the text to the screenshot we create a new canvas element
                const canvas = document.createElement("canvas");
                const context = canvas.getContext("2d");
                canvas.height = imageData.height;
                canvas.width = imageData.width;

                // add the screenshot data to the canvas
                context.putImageData(imageData, 0, 0);
                context.font = "20px Arial";
                context.fillStyle = "#000";
                context.fillRect(
                    0,
                    imageData.height - 40,
                    context.measureText(text).width + 20,
                    30
                );

                // add the text from the textInput element
                context.fillStyle = "#fff";
                context.fillText(text, 10, imageData.height - 20);

                return canvas.toDataURL();
            }

            function downloadImage(filename, dataUrl) {
                // the download is handled differently in Microsoft browsers
                // because the download attribute for <a> elements is not supported
                if (!window.navigator.msSaveOrOpenBlob) {
                    // in browsers that support the download attribute
                    // a link is created and a programmatic click will trigger the download
                    const element = document.createElement("a");
                    element.setAttribute("href", dataUrl);
                    element.setAttribute("download", filename);
                    element.style.display = "none";
                    document.body.appendChild(element);
                    element.click();
                    document.body.removeChild(element);
                } else {
                    // for MS browsers convert dataUrl to Blob
                    const byteString = atob(dataUrl.split(",")[1]);
                    const mimeString = dataUrl
                        .split(",")[0]
                        .split(":")[1]
                        .split(";")[0];
                    const ab = new ArrayBuffer(byteString.length);
                    const ia = new Uint8Array(ab);
                    for (let i = 0; i < byteString.length; i++) {
                        ia[i] = byteString.charCodeAt(i);
                    }
                    const blob = new Blob([ab], { type: mimeString });

                    // download file
                    window.navigator.msSaveOrOpenBlob(blob, filename);
                }
            }
            // button to hide the print preview html element
            document
                .getElementById("closeBtn")
                .addEventListener("click", function () {
                    screenshotDiv.classList.add("hide");
                });





        });
    </script>
</head>
<body>
<div id="viewDiv" class="esri-widget">
    <button id="screenshotBtn"
            class="action-button esri-widget"
            aria-label="Select screenshot area"
            title="Select screenshot area">
        选择截图区域
    </button>
</div>
<div id="screenshotDiv" class="hide">
    <img class="js-screenshot-image"/>
    <div>
        <label>设置要在图像上显示的文本: </label
        ><input type="text" placeholder="Image text" id="textInput" autofocus/>
    </div>
    <button id="downloadBtn"
            class="action-button"
            aria-label="Download image"
            title="Download image">
        下载图片
    </button>
    <button id="closeBtn"
            class="action-button"
            aria-label="Back to webscene"
            title="Back to webscene">
        返回图层
    </button>
</div>
<div id="maskDiv" class="hide screenshotCursor"></div>
</body>
</html>
